package com.company.test30.CharSoftware;

import javax.swing.*;
import java.awt.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Created by v on 16-12-6.
 */
public class GroupChatServer extends JApplet implements Runnable{
    private JTextArea jta=new JTextArea();
    private ServerSocket server;
    private Set<DataOutputStream> outputs=new HashSet<>();

    @Override
    public void init() {
        super.init();
        jta.setFont(new Font("微软雅黑",0,15));
        add(jta);
        Thread thread=new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        try{
            server=new ServerSocket(8000);
            while (true){
                Socket socket=server.accept();
                //报告连入信号
                jta.append(socket.getInetAddress().getHostAddress()+'\n');
                Thread thread=new Thread(new RunClient(socket));
                thread.start();
            }
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    class RunClient implements Runnable{
        Socket socket;
        String name;

        public RunClient(Socket socket){
            this.socket=socket;
        }

        @Override
        public void run() {
            DataOutputStream output=null;
            DataInputStream input;
            try{
                input=new
                        DataInputStream(socket.getInputStream());
                output=new
                        DataOutputStream(socket.getOutputStream());

                //把流添加进公共流中
                synchronized (outputs){ outputs.add(output); }

                //先确认姓名
                name=input.readUTF();

                while (true){
                    //假若链接失败其会自动断开
                    String message=input.readUTF();
                    Thread thread=new Thread(new SendMessage(output,message));
                    thread.start();
                }
            }catch (EOFException ex){
                //当出现这个错误时，证明input已经断开这时候就要把output除掉
                outputs.remove(output);
                ex.printStackTrace();
            }
            catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }

    class SendMessage implements Runnable{
        DataOutputStream output;
        String message;

        public SendMessage(DataOutputStream output, String message){
            this.output=output;
            this.message=message;
        }

        @Override
        public void run() {
            synchronized (outputs){
                for (DataOutputStream output : outputs) {
                    //不给发送信息者推送信息
                    if (output == this.output) {
                        continue;
                    }

                    try {
                        output.writeUTF(message);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    }
}
